﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using Medianamik.Core.Sugar;

namespace Medianamik.Core.DAL
{
    public static class DALExtensions
    {
        public static IEnumerable<T> ReorderByIds<T>(this IEnumerable<T> collection,
            IEnumerable<Guid> ids) where T : IMedianamikDTO
        {
            foreach (var guid in ids.Where(g => collection.Any(i => i.NodeId.Equals(g))))
            {
                yield return collection.First(c => c.NodeId.Equals(guid));
            }
        }

        public static IEnumerable<T> ReorderByIds<T>(this IEnumerable<T> collection,
            string ids) where T : IMedianamikDTO
        {
            return collection.ReorderByIds(DataUtil.GetSelectedGuids(ids));
        }

        public static string SerializeProperties(this IEnumerable<NodePropertyValueLite> properties/*, bool valideXmlCharacters*/, string cultureName)
        {
            var settings = new XmlWriterSettings
                   {
                       Encoding = new UnicodeEncoding(false, false),
                       Indent = false,
                       OmitXmlDeclaration = true,
                       CheckCharacters = true
                   };

            using (var textWriter = new StringWriterWithEncoding(Encoding.Unicode))
            {
                using (var writer = XmlWriter.Create(textWriter, settings))
                {
                    writer.WriteStartElement("root");
                    writer.WriteStartElement("properties");

                    foreach (var p in properties.Where(p => p.CultureName == cultureName || cultureName == null))
                    {
                        writer.WriteStartElement("property");
                            writer.WriteElementString("id", p.PropertyId.ToString());
                            writer.WriteStartElement("value");
                            writer.WriteCData(p.Value.SanitizeXmlString());
                            writer.WriteEndElement();
                        //writer.WriteElementString("culture", p.CultureName);
                        writer.WriteEndElement();
                    }

                    writer.WriteEndElement();
                    writer.WriteEndElement();
                    writer.Flush();
                }

                return textWriter.ToString();
            }
        }

        public static IList<NodePropertyValueLite> DeserializeProperties(this string xml, Guid nodeId)
        {
            var xmlProperties = XDocument.Parse(xml);

            return xmlProperties.Element("root").Elements("properties").Elements("property").Select(p =>
                new NodePropertyValueLite
                    {
                        CultureName = p.Element("culture") == null ? null : p.Element("culture").Value,
                        NodeId = nodeId,
                        PropertyId = new Guid(p.Element("id").Value),
                        Value = p.Element("value").Value
                    }).ToList();
        }

        public static IList<NodePropertyValueLite> ApplyCulture(this IList<NodePropertyValueLite> nodePropertyValueLites, string cultureName)
        {
            if (cultureName != null)
            {
                nodePropertyValueLites.ForEach(n =>
                                                   {
                                                       if (n.CultureName == null)
                                                       {
                                                           n.CultureName = cultureName;
                                                       }
                                                   });
            }
            return nodePropertyValueLites;
        }

        public sealed class StringWriterWithEncoding : StringWriter
        {
            private readonly Encoding _encoding;

            public StringWriterWithEncoding(Encoding encoding)
            {
                _encoding = encoding;
            }

            public override Encoding Encoding
            {
                get { return _encoding; }
            }
        }
    }
}
